--[[
    作者/B站：人鱼m情未了
    QQ：2787283623
    实现功能：物联网鼠标API HTTPpost
    开源Gitee：https://gitee.com/lua_development/yxzhushou
    教程视频：
        https://www.bilibili.com/video/BV1bi4y127p6?spm_id_from=333.999.0.0
        https://www.bilibili.com/video/BV1nu411X7fw?spm_id_from=333.999.0.0
    更新日志：
        20220423.01（最新）
        20220421.01
        20220219.02
]] 
local VERSION = 20220423.01 -- 版本号
local HTTP = require("socket.http") --Luasocket 扩展库
local JSON = require("JSON") --JSON格式转换库
local Mouse = {
    VERSION = VERSION,
    io = 1, -- 默认1号鼠标
    device_id = "", -- 物联网鼠标 设备服务器ID
    key = "", -- 物联网鼠标 设备服务器api-key
    IP = nil, -- 局域网IP地址
    Log = true, -- ESP8266接收成功并输出日志 false 关闭可提高运行效率
    init = {
        x = -3000,
        y = -3000
    }, -- 鼠标初始化位置
    API = {
        -- 物联网鼠标 API
        MouseClick = "MouseClick", -- 单击/长按
        MouseMove = "MouseMove", -- 移动
        MouseDown = "MouseDown", -- 按下
        MouseUp = "MouseUp", -- 抬起
        MouseSlide = "MouseSlide", -- 滑动
        touchMove = "touchMove",
        KeyboardClick = "KeyboardClick" -- 键盘输入
    }
}

function Mouse:new(t) -- 创建对象
    if type(t) == "table" then
        for key, _ in pairs(self) do
            if type(t[key]) == type(self[key]) then
                self[key] = t[key]
            end
        end
    end
    return self
end

function Mouse:HttpPOST(tab_api)
    local request_body = JSON.encode(tab_api)
    local response_body = {}
    local url = "http://api.heclouds.com/cmds?device_id=" .. self.device_id -- 设备服务器ID
    if self.IP then
        url = "http://" .. self.IP -- 局域网
    end
    local res, code, response_headers = HTTP.request {
        url = url, -- 设备服务器ID
        method = "POST",
        headers = {
            ["Content-Type"] = "application/json",
            ["Content-Length"] = #request_body,
            ["api-key"] = self.key -- 设备服务器api-key
        },
        source = ltn12.source.string(request_body),
        sink = ltn12.sink.table(response_body)
    }
end

function Mouse:MouseDown(t) -- 按下
    t = t or {}
    t.io = t.io or self.io
    self:HttpPOST({
        API = self.API.MouseDown,
        Log = self.Log,
        data = t
    })
end

function Mouse:MouseMove(t) -- 相对移动
    t = t or {}
    t.io = t.io or self.io
    self:HttpPOST({
        API = self.API.MouseMove,
        Log = self.Log,
        data = t
    })
end

function Mouse:MouseUp(t) -- 抬起
    t = t or {}
    t.io = t.io or self.io
    self:HttpPOST({
        API = self.API.MouseUp,
        Log = self.Log,
        data = t
    })
end

function Mouse:MouseClick(t) -- 单片机单击/长按
    t = t or {
        sleep = 50
    }
    t.io = t.io or self.io
    t.sleep = t.sleep or 50
    self:HttpPOST({
        API = self.API.MouseClick,
        Log = self.Log,
        data = t
    })
    mSleep(t.sleep + 50) -- 脚本等待单片机执行完毕
end
function Mouse:MouseSlide(t) -- 单片机滑动
    t = t or {}
    t.io = t.io or self.io
    t.INIT_X = t.INIT_X or self.init.x
    t.INIT_Y = t.INIT_Y or self.init.y
    self:HttpPOST({
        API = self.API.MouseSlide,
        Log = self.Log,
        data = t
    })
    mSleep(3000) -- 脚本等待单片机执行完毕
end

function Mouse:touchMove(t) -- 绝对坐标移动
    t = t or {}
    t.io = t.io or self.io
    t.INIT_X = t.INIT_X or self.init.x
    t.INIT_Y = t.INIT_Y or self.init.y
    self:HttpPOST({
        API = self.API.touchMove,
        Log = self.Log,
        data = t
    })
    mSleep(1000) -- 脚本等待单片机执行完毕
end

function Mouse:touchSlide(t) -- 脚本自定义滑动
    t = t or {}
    t.io = t.io or self.io
    t.x = t.x or 0
    t.y = t.y or 0
    t.x1 = t.x1 or 0
    t.y1 = t.y1 or 0
    t.INIT_X = t.INIT_X or self.init.x
    t.INIT_Y = t.INIT_Y or self.init.y
    self:MouseMove({
        io = t.io,
        x = t.INIT_X,
        y = t.INIT_Y
    })
    mSleep(400)
    self:MouseMove({
        io = t.io,
        x = t.x,
        y = t.y
    }) -- 移动指定位置
    mSleep(150)
    self:MouseDown({
        io = t.io
    }) -- 按下
    mSleep(150)
    self:MouseMove({
        x = t.x1 - t.x,
        y = t.y1 - t.y
    }) -- 相对移动
    mSleep(400)
    self:MouseUp({
        io = t.io
    }) -- 抬起
end

function Mouse:KeyboardClick(t)
    t = t or {}
    local io = t.io or self.io
    t.io = nil
    self:HttpPOST({
        API = self.API.KeyboardClick,
        Log = self.Log,
        data = t,
        io = io
    })
end

-- Mouse:new(
--     {
--         device_id = "896539182",              --物联网鼠标 设备服务器ID
--         key = "O3OdFlHoJCRtdZChXIbGVc87Ym0=", --物联网鼠标 设备服务器api-key
--         io = 1,                               -- 默认1号鼠标
--     }
-- )

-- Mouse:new(
--     {
--         IP = "192.168.3.3"                    -- 局域网
--         io = 2,                               -- 默认2号鼠标
--     }
-- )

-- Mouse:touchMove({x = 500, y = 100})
-- Mouse:MouseSlide({x = 500, y = 100})
-- Mouse:MouseClick({sleep = 5000})

return Mouse
